home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / jam / jamdisk4 / arptools / src / tail.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  5KB  |  236 lines

  1. /*
  2.  
  3.           Tail - Display the last lines of a file.
  4.  
  5.           Original effort by Fabio Rossetti. Inspired by the tail program
  6.           by Gary Brant found on <>< 179.
  7.  
  8.       (c) 1989 by Fabio Rossetti
  9.  
  10.       To compile under Lattice C v5.0x use:
  11.  
  12.         lc  -O -v -cus tail
  13.         blink lib:cres.o tail.o to tail lib lib:a.lib lib:lc.lib sd nd
  14.  
  15. */
  16.  
  17. #include <exec/types.h>
  18. #include <exec/memory.h>
  19. #include <exec/libraries.h>
  20. #include <libraries/dos.h>
  21. #include <libraries/dosextens.h>
  22. #include <libraries/arpbase.h>
  23. #include <arpfunctions.h>
  24. #include <proto/exec.h>
  25. #include <proto/dos.h>        
  26.  
  27. struct ArpBase *ArpBase=NULL;
  28. struct Process *Pr;
  29. LONG argc;
  30.  
  31. #define NARGS 4
  32. #define BFSIZE 256    
  33. #define FROM    argv[0]
  34. #define TO    argv[1]
  35. #define LIN    argv[2]
  36. #define BAN    argv[3]
  37. STRPTR argv[NARGS];
  38. #define MAXLIN 256
  39. TEXT *Lin[256];
  40.  
  41.     
  42. TEXT *Buf,*OBuf;
  43. TEXT Banner[256];
  44.  
  45. struct UserAnchor {
  46.     struct    AnchorPath    ua_AP;
  47.     BYTE    moremem[255];    /* extension */
  48. };
  49. struct    UserAnchor *Anchor=NULL;
  50.  
  51. /* Trick to keep code down to size */
  52. VOID MemCleanup()
  53. {
  54. }
  55.  
  56. /* shutdown routine */
  57. VOID Cleanup(r1,r2,msg)
  58. LONG r1,r2;
  59. STRPTR msg;
  60. {
  61.     if (msg) Puts(msg);
  62.     if (ArpBase) CloseLibrary((struct Library *)ArpBase);
  63.     Pr->pr_Result2 = r2;
  64.     exit(r1);
  65. }
  66.  
  67. VOID Tail(Inp,Out,lines)
  68. BPTR Inp,Out;
  69. ULONG lines;
  70.  
  71. {
  72.  
  73.     REGISTER TEXT *il = Lin[0];
  74.     REGISTER LONG count, obp=0,p=0,i,fl=0;
  75.  
  76.     /* enqueue the last lines read */
  77.     for(;;) {
  78.     /* read until eof */
  79.     if (!obp) if (!(count = Read(Inp,Buf,BFSIZE))) {        
  80.             /* the last line */    
  81.             if(fl) {
  82.             *il = '\0';
  83.             p++;}
  84.             break;
  85.             }
  86.     fl = 1;
  87.     if (*(Buf + obp) == '\n') {
  88.         fl = 0; 
  89.         ++obp;
  90.         *il = '\0';
  91.         p++;
  92.         il = Lin[p%lines];
  93.  
  94.         if (SetSignal(0,0) & SIGBREAKF_CTRL_C) 
  95.             Cleanup(RETURN_WARN,NULL,"***Break");
  96.            }
  97.     else 
  98.     {
  99.     if (((TEXT *)il - (TEXT *)Lin[p%lines]) > MAXLIN)
  100.             Cleanup(RETURN_FAIL,NULL,"Buffer overflow");
  101.     *il++ = *(Buf + obp++);
  102.     }
  103.  
  104.     if (obp == count) obp = 0;
  105.  
  106. }
  107.  
  108.     /* display queue */
  109.     if (p <= lines) for(i=0; i < p; i++) FPrintf(Out,"%s\n",Lin[i]);
  110.     else {
  111.     for(i=(p%lines); i < lines; i++) {
  112.         if (SetSignal(0,0) & SIGBREAKF_CTRL_C)
  113.             Cleanup(RETURN_WARN,NULL,"***Break");
  114.         FPrintf(Out,"%s\n",Lin[i]);
  115.         }
  116.  
  117.     if ((lines != 1) && ((p%lines) != 0))
  118.          for(i=0; i <= (p%lines)-1 ; i++) {
  119.             FPrintf(Out,"%s\n",Lin[i]);
  120.             if (SetSignal(0,0) & SIGBREAKF_CTRL_C) 
  121.                 Cleanup(RETURN_WARN,NULL,"***Break");
  122.                 }
  123.     }
  124. }
  125.  
  126. VOID _main(Line)
  127. STRPTR Line;
  128. {
  129.  
  130.  
  131.  
  132.     BPTR infh,outfh;
  133.     LONG Lines,Result,i=0,j;
  134.     char **ArV;
  135.     Pr = (struct Process*)FindTask(NULL);
  136.     
  137.     
  138.     if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion)))
  139.             Cleanup(RETURN_FAIL,ERROR_INVALID_RESIDENT_LIBRARY,NULL);
  140.     
  141.     /* parse command line */
  142.     for (argc=0;argc < NARGS ;++argc)
  143.         argv[argc] = (STRPTR) NULL;
  144.  
  145.     while(*Line > ' ')
  146.         ++Line;
  147.  
  148.     if((argc = GADS(++Line,
  149.         strlen(Line),
  150.         "Usage: Tail [Files file1 file2 ...] [TO filename] [LIN linenumber] [BAN]",
  151.         argv,
  152.         "Files/...,TO/K,LIN/K,BAN/S" )) < 0)
  153.             Cleanup(RETURN_WARN,NULL,FROM);
  154.  
  155.         if (!(Buf = ArpAllocMem(BFSIZE,MEMF_CLEAR))) 
  156.             Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error: no memory");
  157.  
  158.     if ( Anchor = (struct UserAnchor *)ArpAlloc( (ULONG)sizeof( *Anchor )) )
  159.     {
  160.         Anchor->ua_AP.ap_Length = 255;    /* Want full path built */
  161.         
  162.     }
  163.     else Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error:No memory");
  164.     
  165.     
  166.     if (LIN) {
  167.     Lines = Atol(LIN);
  168.     if((Errno == ERRBADINT) || (Lines <=0)) Cleanup(RETURN_ERROR,NULL,"Bad args");
  169.     if(Lines > 255) Cleanup(RETURN_WARN,NULL,"Too many lines");
  170.     }
  171.     else Lines = 10;
  172.  
  173.     /* set up queue */
  174.     for (j = 0; j < Lines; j++) {
  175.         if (!(Lin[j]=ArpAllocMem(MAXLIN,MEMF_CLEAR)))
  176.         Cleanup(RETURN_ERROR,ERROR_NO_FREE_STORE,"Error: no memory!");
  177.                   }
  178.     if(TO) {
  179.             if(!(outfh=ArpOpen(TO,MODE_NEWFILE))) {
  180.                 Printf("Can't open %s\n",TO);
  181.                 Cleanup(RETURN_ERROR,ERROR_OBJECT_NOT_FOUND,NULL);
  182.                 }
  183.             }
  184.     else outfh = Output();
  185.  
  186.  
  187.     ArV = (char **)FROM;
  188.     if (ArV[0]) {
  189.  
  190.     if ( Anchor = (struct UserAnchor *)ArpAlloc( (ULONG)sizeof( *Anchor )) )
  191.     {
  192.         Anchor->ua_AP.ap_Length = 255;    /* Want full path built */
  193.         
  194.     }
  195.     else
  196.         Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error: no memory");
  197.     
  198.     while (ArV[i] != NULL) {
  199.  
  200.     Result = FindFirst(ArV[i],(struct AnchorPath*) Anchor);
  201.  
  202.     while (Result == 0) {
  203.  
  204.         if (Anchor->ua_AP.ap_Info.fib_DirEntryType < 0) {
  205.             if(!(infh=ArpOpen(Anchor->ua_AP.ap_Buf,MODE_OLDFILE))) {
  206.                 Printf("Can't open %s\n",FROM);
  207.                 Cleanup(RETURN_ERROR,ERROR_OBJECT_NOT_FOUND,NULL);
  208.                     }
  209.             else {
  210.                 if (BAN) {
  211.                     PathName(ArpLock(Anchor->ua_AP.ap_Buf,
  212.                     ACCESS_READ),Banner,255);
  213.                     FPrintf(outfh,"*** File %s ***\n",
  214.                     Banner);
  215.                     }
  216.             Tail(infh,outfh,Lines);
  217.             }
  218.             }
  219.         else {
  220.             Printf("%s is a directory !\n",ArV[i]);
  221.             Cleanup(RETURN_ERROR,ERROR_OBJECT_WRONG_TYPE,NULL);
  222.             }
  223.  
  224.         Result = FindNext((struct AnchorPath*) Anchor );    
  225.         }
  226.         i++;
  227.         }
  228.     }
  229.     
  230.     else Tail(Input(),outfh,Lines);
  231.  
  232.     Cleanup(NULL,NULL,NULL);
  233.  
  234.  
  235. }
  236.